package
{
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.ui.Keyboard;
	
	import org.papervision3d.cameras.FreeCamera3D;
	
	public class Movement3D
	{
		private var movementCamera:FreeCamera3D;	//Die Kamera auf die die Bewegung Auswirkung haben soll
		private var inertia:Number = 3;				//Faktor für für die Geschwindigkeit
		private var keyRight:Boolean = false;		//Flag - Rechtsbewegung im nächsten Frame
		private var keyLeft:Boolean = false;		//Flag - Linksbewegung im nächsten Frame
		private var keyForward:Boolean = false;		//Flag - Vorwärtsbewegung im nächsten Frame
		private var keyBackward:Boolean = false;	//Flag - Rückwärtsbewegung im nächsten Frame
		private var forwardFactor:Number = 0;		//Faktor für die Rückwärts/Vorwärtsbewegung
		private var sideFactor:Number = 0;			//Faktor für die Links/Rechtsbewegung
		private var movementStage:Stage;			//Bühne für die Events
		
		/**
		 * Kamera und stage speichern
		 */
		public function Movement3D(cCamera:FreeCamera3D,cStage:Stage)
		{
			//Kamera und Stage speichern
			movementCamera = cCamera;
			movementStage = cStage;
	
			//Listener anstarten um Bewegung zu bauen
			movementStage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
			movementStage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
			movementStage.addEventListener(MouseEvent.MOUSE_WHEEL,zoom);	
		}
		
		/**
		 * Kamera zoom
		 */
		private function zoom(e:MouseEvent):void{
			trace(e);
			if(e.delta > 0){
				movementCamera.zoom += 0.1;
			}
			else{
				movementCamera.zoom -= 0.1;
			}
		}
		
		/**
		 * Die gedrückte Taste feststellen und die Flags für
		 * die Positionsänderung setzen
		 * @param e Das KeyboardEvent
		 */
		private function onKeyDown(e:KeyboardEvent):void {
			//Welche Taste wurde gedrückt
			switch( e.keyCode ) {
				case "W".charCodeAt():
				case Keyboard.UP:
					keyForward = true;
					keyBackward = false;
				break;
	
				case "S".charCodeAt():
				case Keyboard.DOWN:
					keyBackward = true;
					keyForward = false;
				break;
	
				case "A".charCodeAt():
				case Keyboard.LEFT:
					keyLeft = true;
					keyRight = false;
				break;
	
				case "D".charCodeAt():
				case Keyboard.RIGHT:
					keyRight = true;
					keyLeft = false;
				break;
			}
		}
		
		/**
		 * Welche Taste wurde wieder los gelassen und welche Flag wird resetet
		 * @param e Das KeyboardEvent
		 */
		private function onKeyUp(e:KeyboardEvent):void
		{
			switch( e.keyCode ){
				case "W".charCodeAt():
				case Keyboard.UP:
					keyForward = false;
				break;
	
				case "S".charCodeAt():
				case Keyboard.DOWN:
					keyBackward = false;
				break;
	
				case "A".charCodeAt():
				case Keyboard.LEFT:
					keyLeft = false;
				break;
	
				case "D".charCodeAt():
				case Keyboard.RIGHT:
					keyRight = false;
				break;
			}
		}
		
		/**
		 * Die per Tasten eingegeben Positionsänderungswünsche umsetzen.
		 * Die Maus verursacht einen Kameraschwenk.
		 */
		public function update():void{
			//Die Bewegungsfaktoren werden gesetzt
			if(keyForward){
				forwardFactor += 50;
			}
			if(keyBackward){
				forwardFactor += -50;
			}
			if(keyLeft){
				sideFactor += -50;
			}
			if(keyRight){
				sideFactor += 50;
			}
			
			//Mit der Stärke verrechnen
			forwardFactor +=( 0-forwardFactor ) / inertia;
			sideFactor += ( 0 - sideFactor ) / inertia;
			
			//Gibt es eine Vorwätsbewegung
			if (forwardFactor > 0){
				movementCamera.moveForward( forwardFactor );
			}
			//Sonst Rückwärtsbewegung
			else{
				movementCamera.moveBackward( -forwardFactor );
			}
			
			//Bewegung nach Links und Rechts
			if (sideFactor > 0){
				movementCamera.moveRight( sideFactor );
			}else{
				movementCamera.moveLeft( -sideFactor );
			}
			
			//Die Kameraschwenks werden von der Mausposition errechnet
			movementCamera.rotationX = -(movementStage.mouseY - movementStage.height / 2) / 5;
			movementCamera.rotationY = (movementStage.mouseX - movementStage.width / 2) / 5;
			
		}
	}
}